package com.stk.doublebreak;

import java.util.ArrayList;
import java.util.Random;

import org.andengine.engine.camera.Camera;
import org.andengine.engine.handler.timer.ITimerCallback;
import org.andengine.engine.handler.timer.TimerHandler;
import org.andengine.engine.options.EngineOptions;
import org.andengine.engine.options.EngineOptions.ScreenOrientation;
import org.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy;
import org.andengine.entity.Entity;
import org.andengine.entity.modifier.AlphaModifier;
import org.andengine.entity.modifier.ParallelEntityModifier;
import org.andengine.entity.modifier.ScaleModifier;
import org.andengine.entity.modifier.SequenceEntityModifier;
import org.andengine.entity.scene.Scene;
import org.andengine.entity.scene.Scene.IOnSceneTouchListener;
import org.andengine.entity.scene.background.Background;
import org.andengine.entity.util.FPSLogger;
import org.andengine.input.touch.TouchEvent;
import org.andengine.opengl.font.Font;
import org.andengine.opengl.font.FontFactory;
import org.andengine.opengl.texture.TextureOptions;
import org.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlas;
import org.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlasTextureRegionFactory;
import org.andengine.opengl.texture.region.ITextureRegion;
import org.andengine.ui.activity.SimpleBaseGameActivity;

import android.graphics.Color;
import android.graphics.Typeface;
import android.util.Log;
import android.view.Display;
import android.view.MotionEvent;

public class DoubleBreakActivity extends SimpleBaseGameActivity implements  IOnSceneTouchListener{

	private int width;
	private int height;
	private Camera camera;
	private Scene mainScene;
	private ArrayList<Asteroid> asteroids;
	private Player p;
	private int level;
	private BitmapTextureAtlas bitmapTextureAtlas;
	private ITextureRegion particleTextureRegion;
	private Font mFont;
	private Scorer scorer;

	@Override
	public EngineOptions onCreateEngineOptions() {
		Display display = getWindowManager().getDefaultDisplay();
		this.width = display.getWidth();
		this.height = display.getHeight();
		
		camera = new Camera(0, 0, width, height);
		
		final EngineOptions engineOptions =  new EngineOptions(true, ScreenOrientation.LANDSCAPE_FIXED, new RatioResolutionPolicy(this.width, this.height), camera);

		engineOptions.getTouchOptions().setNeedsMultiTouch(true);

		return engineOptions;
	}

	@Override
	protected void onCreateResources() {
		BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/");
		
		
		//CREATE IMAGES FOR PARTICLES
		this.bitmapTextureAtlas = new BitmapTextureAtlas(this.getTextureManager(), 32, 32, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
		this.particleTextureRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.bitmapTextureAtlas, this, "particle_fire.png", 0, 0);

		this.mEngine.getTextureManager().loadTexture(this.bitmapTextureAtlas);
		
		
		//CREATE FONTS
		Typeface typeface = Typeface.create(Typeface.DEFAULT, Typeface.BOLD);
		this.mFont = FontFactory.create(this.getFontManager(), this.getTextureManager(), 512, 512, TextureOptions.BILINEAR, typeface, 128, true, Color.WHITE);
		this.mFont.load();
	}

	@Override
	protected Scene onCreateScene() {
		this.mEngine.registerUpdateHandler(new FPSLogger());		
		
		this.level = 1;
		
		this.mainScene = new Scene();
		this.mainScene.setBackground(new Background(0f, 0f, 0f));
		this.mainScene.setOnSceneTouchListener(this);
		this.mainScene.setTouchAreaBindingOnActionDownEnabled(true);
		//create layers (2 for game and score)
		for(int i = 0; i < 2; i++) {
			this.mainScene.attachChild(new Entity());
		}
		
		asteroids =  new ArrayList<Asteroid>();
		
		//Cleaning screen for asteroids already out & game logic
		this.mainScene.registerUpdateHandler(new TimerHandler(0.5f, true, new ITimerCallback() {	
			int numberOfAsteroids = 0;
			int elapsedShowing = 0;
			boolean playing = false;
			boolean waiting = false;
			boolean showing = true;
			boolean register = true;
			int newColor;

			@Override
			public void onTimePassed(final TimerHandler pTimerHandler) {
				//Delete asteroids
				if (asteroids.size() > 0){
					ArrayList<Asteroid> asteroidsStillActive = new ArrayList<Asteroid>();
					for (Asteroid a : asteroids){
						if (!a.checkOut()){
							asteroidsStillActive.add(a);
						}else{
							for (Segment s : a.getShape()){
								mainScene.getChild(0).detachChild(s);
							}
							for (Segment s : a.getShadow()){
								mainScene.getChild(0).detachChild(s);
							}
							mainScene.getChild(0).detachChild(a.getCore());
						}
					}				
					asteroids = asteroidsStillActive;
				}					

				//Update asteroids
				if (showing){
					elapsedShowing++;
				}

				if (playing && numberOfAsteroids < (10 + level*5)){
					Asteroid a = new Asteroid(width, height, DoubleBreakActivity.this.getVertexBufferObjectManager(), 4, 100);
					for (int i = 0; i < a.getShape().length; i++){
						mainScene.getChild(0).attachChild(a.getShadow()[i]);
						mainScene.getChild(0).attachChild(a.getShape()[i]);
					}				
					mainScene.getChild(0).attachChild(a.getCore());
					asteroids.add(a);
					numberOfAsteroids++;
				}else if (elapsedShowing >= 16 && showing){
					elapsedShowing = 0;
					showing = false;
					playing = true;
				}else if (numberOfAsteroids >= (10 + level*5) && playing){
					playing = false;
					waiting = true;	
				}else if (waiting && asteroids.size() == 0){
					level ++;
					waiting = false;
					showing = true;
					register = true;
					elapsedShowing = 0;
					numberOfAsteroids = 0;
				}else if (register){
					register = false;	
					Random rand  = new Random();
					newColor = rand.nextInt(4);
					p.changeColor(newColor);
					scorer.updateOnNewLevel(level, newColor);
				}

			}
		}));

		//Add the text
		scorer = new Scorer(width, height, mFont, this.getVertexBufferObjectManager());			

		//Start the player and its smoke
		p =  new Player(this.getVertexBufferObjectManager(), this.particleTextureRegion, this.level, this.width, this.height);

		this.mainScene.getChild(1).attachChild(scorer.getLifeOuter());
		this.mainScene.getChild(1).attachChild(scorer.getLifeInner());
		this.mainScene.getChild(1).attachChild(scorer.getLife());
		this.mainScene.getChild(1).attachChild(scorer.getText());
		this.mainScene.getChild(1).attachChild(scorer.getHelp());

		this.mainScene.getChild(0).attachChild(p.getLeftSmoke());
		this.mainScene.getChild(0).attachChild(p.getRightSmoke());
		this.mainScene.getChild(0).attachChild(p.getShadow());
		this.mainScene.getChild(0).attachChild(p);

		return mainScene;
	}

	@Override
	public boolean onSceneTouchEvent(final Scene pScene, final TouchEvent pSceneTouchEvent) {
		int action = pSceneTouchEvent.getMotionEvent().getAction();
		if (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_MOVE || action == MotionEvent.ACTION_UP){
			if (pSceneTouchEvent.getMotionEvent().getPointerCount() >= 2 ){
				this.p.setPosition(pSceneTouchEvent.getMotionEvent().getX(0), 
						pSceneTouchEvent.getMotionEvent().getY(0), 
						pSceneTouchEvent.getMotionEvent().getX(1), 
						pSceneTouchEvent.getMotionEvent().getY(1));
				this.checkCollisions();
			}
		}


		return false;
	}
	
	public void checkCollisions(){
		if (asteroids.size() > 0){
			ArrayList<Asteroid> asteroidsStillActive = new ArrayList<Asteroid>();
			for (Asteroid a : asteroids){
				if (!a.collidesWithPlayer(p)){
					asteroidsStillActive.add(a);
				}else{
					for (Segment s : a.getShape()){
						mainScene.getChild(0).detachChild(s);
					}
					for (Segment s : a.getShadow()){
						mainScene.getChild(0).detachChild(s);
					}
					mainScene.getChild(0).detachChild(a.getCore());
					if (p.getColorShape() == a.getShape().length){
						scorer.increaseLife();
					}else{
						scorer.decreaseLife();
					}
				}
			}				
			asteroids = asteroidsStillActive;
		}		
	}
}